package server

import scala.actors._
import scala.math._
import scala.collection.mutable._
import assignments._

/**
 * Container to process assignment requests
 * @author Jacob Biggs
 *
 */
class AssignmentPool extends Actor {
	
  val unassigned = new ListBuffer[ Assignment ]
  val assigned = new ListBuffer[ Assignment ]
  
  val results = new ListBuffer[ AssignmentResult ]
  
	def act()
	{
    val newTasks = new ListBuffer[ ProjectTask ]
      
      for(i <- 1 to 130)
      {
        newTasks += new ProjectTask (i, 
                                     () => {
                                             var sum : BigInt = 0
                                             for(num <- 1 to i*1000000) sum += num
                                             sum
                                           })
      }
    
    // Create an assignment of test tasks to do some basic math operations
    unassigned += new Assignment(0, 0, newTasks){
      var sum : BigInt = 0;
      
      override def pack()
      {
        for(result <- this.results)
        {
          // Print each result
          println("Task #" + result.taskId + " result: " + result.value.get)
          // Add all results
          this.sum += result.value.get.asInstanceOf[BigInt]
        }
        println("Final sum: " + this.sum)
      }
      
      override def collect() : AssignmentResult =
      {
        AssignmentResult( this.id , Some(this.sum) )
      }
    }
    
	  loop
	  {
		  react
		  {
		    case messages.RequestAssignment(level) =>
		      println("New assignment level " + level + " requested")
		      val option = unassigned.find(assignment => assignment.level == level)
		      
		      option match
		      {
		        case Some(assignment) => 
		          assigned + assignment
	            sender ! assignment
	            println("Assignment found and sent to client")
		        case None =>
		          sender ! messages.AssignmentUnavailable
		          println("No assignment found, alerting client")
		      }
		      
		    case assignmentResult : AssignmentResult =>
		      results += assignmentResult
		  }
	  }
  }

}